globalConfig = {
    redisHost: '47.244.129.234',
    redisPort: '6379',
    redisPassword: '5JyY7wyDLdvNS9qFPiWrdgcsYRHhbbMxtiRoQ3EsvFLCxkRs6Gs',

    mysqlHost: '47.244.107.82',
    mysqlUser: 'lognumber',
    mysqlPassword: 'eLn3X8ynkhSNJpib',
    mysqlPort: '3306',
    mysqlDataBase: 'lognumber'
};

var commander = require('commander');
var async = require('async');
const { exec } = require('child_process');
module.exports = {
    ready: function () {
        commander.version('1.0.0')
            .option('-a, --account', '合约账号')
            .option('-p, --path', '合约文件本地路径')
            .option('-c, --contract', '合约文件本地文件名')
            .parse(process.argv);
        return commander;
    },

    initDict: {},
    initList: {},

    begin: function () {
        console.log('欢迎使用[M.S.]引擎'.green);
        if (Object.keys(this.initList).length) {
            console.log('串行启动'.yellow);
            async.series(this.initList, function (error, result) { });
        }
        else if (Object.keys(this.initDict).length) {
            console.log('并行启动'.yellow);
            async.parallel(this.initDict, function (error, result) { });
        }
        return;
        //var done_sum = 0;
        //var error_sum = 0;
        //for (var i = 0; i < this.initList.length; i++) {
        //    this.initList[i](function (done = false) {
        //        if (done) {
        //            console.log('成功');
        //            done_sum++;
        //            if (done_sum === this.initList.length) {
        //                return this.main();
        //            }
        //        }
        //        else {
        //            error_sum++;
        //            console.log('失败');
        //        }
        //    });
        //}
    },

    cleos: function (node_url, _cmd, completed, echo = false, force = false) {
        var cmd = this.cleosExe + ' --url ' + node_url + ' ' + _cmd;
        if (force) {
            cmd += ' -f';
        }
        console.log(cmd.green);

        exec(cmd, (err, stdout, stderr) => {
            if (completed) { completed(err, stdout, stderr); }

            if (err) {
                if (echo) { console.log(err); }
                return;
            }

            if (echo && stdout) {
                console.log(stdout);
            }

            if (echo && stderr) {
                console.log(stderr);
            }
        });
    },

    cleosExe: 'cleos',

    checkDockerEOS: function (node_url, callBackFun) {
        var self = this;
        const { exec } = require('child_process');
        async.parallel({
            paraA: function (done) {
                exec('cleos --url ' + node_url + ' get info', (err, stdout, stderr) => {
                    if (err) { done(null, false); return; }
                    if (stdout) { done(null, true); console.log(stdout); return; }
                    if (stderr) { done(null, true); console.log(stderr); return; }
                });
            },
            paraB: function (done) {
                exec('docker exec eos cleos --url ' + node_url + ' get info', (err, stdout, stderr) => {
                    if (err) { done(null, false); return; }
                    if (stdout) { done(null, true); console.log(stdout); return; }
                    if (stderr) { done(null, true); console.log(stderr); return; }
                });
            }
        }, function (error, result) {

            if (result.paraA) {
                self.cleosExe = 'cleos';
            }
            else if (result.paraB) {
                self.cleosExe = 'docker exec eos cleos';
            }
            else {
                self.cleosExe = '';
                console.error('未检测到任何可用cleos'.red);
                process.exit();
            }
            setTimeout(callBackFun, 0, self.cleosExe);
        });

        //exec('cleos --url ' + node_url + ' get info', (err, stdout, stderr) => {
        //    if (err) { if (isCleos === undefined) { isCleos = false; } }
        //    if (stdout) { if (isCleos === undefined) { isCleos = true; } }
        //});

        //exec('docker exec eos cleos --url ' + node_url + ' get info', (err, stdout, stderr) => {
        //    if (err) { if (isDocker === undefined) { isDocker = false; } }
        //    if (stdout) { if (isDocker === undefined) { isDocker = true; } }
        //});
        //setTimeout(callBackFun, 0, isCleos, isDocker);
    },

    randomRangeInt: function (min, max) {
        return min + this.randomInt(max - min);
    },

    randomInt: function (max) {
        return Math.floor(Math.random() * Math.floor(max));
    },

    colors: require('colors'),

    fs: require('fs'),

    host: '127.0.0.1',
    port: 80,
    netServer: undefined,

    requireNetServer: function (port = this.host, keypath = '', certpath = '', check_heartbeat = true) {
        var https = require('https');
        var ws = require('ws');

        /*https_options = { key: this.fs.readFileSync(keypath), cert: this.fs.readFileSync(certpath) };

        var https_server = https.createServer(https_options, function (req, res) {
            res.writeHead(403);
            res.end("This is a WebSockets server!\n");
        }).listen(port);
        this.netServer = new ws.Server({ server: https_server });*/

        this.netServer = new ws.Server({ host: "127.0.0.1",
                                         port: 801 });

        var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({ port: 80 });
wss.on('connection', function (ws) {
    console.log('client connected');
    ws.on('message', function (message) {
        console.log(message);
    });
});

        this.netServer.parent = this;
        this.netServer.check_heartbeat = check_heartbeat;
        this.netServer.sock_users = {};
        console.log('ready---------------')
        
        // 注册新连接回调
        /*this.netServer.on('connection', function (conn) {
            console.log('connection--------------');
            conn.login_time = Date.now();
            conn.time_out = Date.now();
            conn.netServer = this;
            conn.sendData = function (data) {
                try {
                    if (conn.readyState !== conn.OPEN) {
                        return;
                    }
                    var opcode = typeof data === 'string' ? true : false;
                    if (opcode) {
                        conn.send(data);
                        //console.log('send:', data);
                    }
                    else {
                        conn.send(JSON.stringify(data));
                        //console.log('send:', JSON.stringify(data));
                    }
                } catch (e) {
                    console.log(e);
                }
            };

            // 注册消息回调
            conn.on("message", function (pack_str) {
                try {
                    if (typeof pack_str === 'string') {
                        pack = JSON.parse(pack_str);
                    }

                    if (pack.type) {
                        this.emit(pack.type, pack);
                    }
                    else {
                        console.log('未知消息', pack);
                        conn.close();
                    }
                }
                catch (e) {
                    console.log(e);
                    conn.close();
                }
            });

            conn.on("close", function (code, reason) {
                try {
                    var tmpStr = '{0}:{1}:{2}'.format(conn._socket.remoteAddress, conn._socket.remotePort, conn.login_time);
                    this.emit('Close', conn);
                    delete this.netServer.sock_users[tmpStr];
                    console.log('断开连接'.red, tmpStr);
                } catch (e) { console.log(e.red); }
            });

            conn.on("error", function (err) {
                this.emit('Error', conn);
                console.log("连接错误");
                console.log(err.red);
            });

            String.prototype.format = this.parent.strFormat;
            var tmpStr = '{0}:{1}:{2}'.format(conn._socket.remoteAddress, conn._socket.remotePort, conn.login_time);
            this.sock_users[tmpStr] = conn;
            console.log('新连接'.green, tmpStr);

            // 是否开启心跳检测
            if (this.check_heartbeat) {
                conn.on("heartbeat", function (code, reason) {
                    var tmpStr = '{0}:{1}:{2}'.format(conn._socket.remoteAddress, conn._socket.remotePort, conn.login_time);
                    this.netServer.sock_users[tmpStr].time_out = Date.now();
                    console.log('心跳'.green, tmpStr);
                    this.emit('Heartbeat', conn);
                });

                conn.check_heartbeat = function () {
                    var tmpStr = '{0}:{1}:{2}'.format(conn._socket.remoteAddress, conn._socket.remotePort, conn.login_time);
                    if (!conn.netServer.sock_users[tmpStr] || !conn.netServer.sock_users[tmpStr].time_out || (conn.netServer.sock_users[tmpStr].time_out + 10000 * 3) < Date.now()) {
                        console.log('心跳超时'.red, tmpStr);
                        this.close();
                    }
                    else {
                        setTimeout(conn.check_heartbeat, 10000 * 3);
                    }
                };
                setTimeout(conn.check_heartbeat, 10000 * 3);
            }
            this.emit('Connection', conn);
        });*/

        return this.netServer;
    },

    requireNetClient: function (host = this.host, port = this.host, need_heartbeat = true) {

        var ws = require('ws');

        var wss = new ws('wss://' + host + ':' + port, {
            rejectUnauthorized: false
        });

        // 连接断开
        wss.on('close', function close() {
            console.log('close');
        });

        // 连接被打开
        wss.on('open', function open() {
            console.log('open');
            this.emit('Open');
        });

        // 发包封装
        wss.sendData = function (data) {
            try {
                if (this.readyState !== this.OPEN) {
                    return;
                }
                var opcode = typeof data === 'string' ? true : false;
                if (opcode) {
                    this.send(data);
                }
                else {
                    this.send(JSON.stringify(data));
                }
            } catch (e) {
                console.log(e);
            }
        };

        // 底层消息路由
        wss.on('message', function (pack_str) {
            try {
                if (typeof pack_str === 'string') {
                    pack = JSON.parse(pack_str);
                }

                if (pack.type) {
                    this.emit(pack.type, pack);
                }
                else {
                    console.log('未知消息', pack);
                    this.close();
                }
            }
            catch (e) {
                if (e) { console.log(e); }
                this.close();
            }
        });

        if (need_heartbeat) {
            wss.heartbeat = function () {
                wss.sendData({ type: 'heartbeat' });
                setTimeout(wss.heartbeat, 10000);
            };
            setTimeout(wss.heartbeat, 10000);
        }
        return wss;
    },

    openRedis: function (redis_log_name) {
        var rediz = require('redis');
        try {
            var redis = rediz.createClient(globalConfig.redisPort, globalConfig.redisHost, { auth_pass: globalConfig.redisPassword });
            console.log('连接'.green, redis_log_name, globalConfig.redisHost, globalConfig.redisPort);
            //redisSubscribe.subscribe('dice1betlog');
            //console.log('redis注册dice1betlog通知'.green);
            return redis;
        }
        catch (e) {
            console.log(e);
        }
    },


    strFormat: function (args) {
        var result = this;
        var reg;
        if (arguments.length > 0) {
            if (arguments.length === 1 && typeof (args) === "object") {
                for (var key in args) {
                    if (args[key]) {
                        reg = new RegExp("({" + key + "})", "g");
                        result = result.replace(reg, args[key]);
                    }
                }
            }
            else {
                for (var i = 0; i < arguments.length; i++) {
                    if (arguments[i]) {
                        reg = new RegExp("({)" + i + "(})", "g");
                        result = result.replace(reg, arguments[i]);
                    }
                }
            }
        }
        return result;
    }

};
